<template>
  <div id="app">
    <alert-modal ref="alertModal"
                 @alert-showed="playAlertSound"
                 @alert-confirmed="stopAlertSound"
    ></alert-modal>
    <div v-if="!mqttConnected" class="connection-banner">
      MQTT连接断开，正在尝试重连...
    </div>
    <router-view />
    <theme-picker/>
  </div>
</template>

<script>
import { Client } from 'paho-mqtt'
import ThemePicker from "@/components/ThemePicker";
import AlertModal from "@/components/AlertModal.vue";

export default {
  name: 'App',
  components: {
    ThemePicker,
    AlertModal
  },
  metaInfo(){
    return {
      title: this.$store.state.settings.dynamicTitle && this.$store.state.settings.title,
      titleTemplate: title => {
        return title ? `${title} - ${process.env.VUE_APP_TITLE}` : process.env.VUE_APP_TITLE
      }
    }
  },
  data() {
    return {
      mqttClient: null,
      mqttConnected: false,
      reconnectAttempts: 0,
      maxReconnectAttempts: 5,
      alertAudio: null // 存储音频对象
    }
  },
  mounted(){
    this.initMQTT()
  },
  methods: {
    initMQTT() {
      const host = process.env.VUE_APP_MQTT_URL;
      const clientId = `web-global-${Math.random().toString(16).substr(2, 8)}`

      this.mqttClient = new Client(host, clientId)

      // 设置MQTT回调
      this.mqttClient.onConnectionLost = this.onConnectionLost
      this.mqttClient.onMessageArrived = this.onMessageArrived

      // 连接选项
      const connectOptions = {
        onSuccess: this.onConnectSuccess,
        onFailure: this.onConnectFailure,
        userName: process.env.VUE_APP_USERNAME,
        password: process.env.VUE_APP_PASSWORD,
        keepAliveInterval: 60,
        reconnect: false // 我们自己实现重连逻辑
      }

      // 开始连接
      this.mqttClient.connect(connectOptions)
    },

    onConnectSuccess() {
      console.log('MQTT连接成功')
      this.mqttConnected = true
      this.reconnectAttempts = 0

      // 连接成功后订阅主题
      this.mqttClient.subscribe('$FAMS/OTU/+/alarm')
    },

    onConnectFailure(error) {
      console.error('MQTT连接失败:', error)
      this.mqttConnected = false
      this.attemptReconnect()
    },

    onConnectionLost(response) {
      console.error('MQTT连接丢失:', response.errorMessage)
      this.mqttConnected = false
      this.attemptReconnect()
    },

    onMessageArrived(message) {
      console.log('收到MQTT消息:', message.topic, message.payloadString)
      try {
        const alertData = JSON.parse(message.payloadString)
        this.$refs.alertModal.showAlert(alertData)
        this.playAlertSound()
      } catch (e) {
        console.error('解析报警消息失败:', e)
      }
    },

    playAlertSound() {
      // 先停止之前的音频
      this.stopAlertSound();

      // 创建新的音频对象
      this.alertAudio = new Audio(require('@/assets/sound/alarm.wav'));
      this.alertAudio.loop = true;

      // 使用Promise处理播放
      const playPromise = this.alertAudio.play();

      if (playPromise !== undefined) {
        playPromise
          .then(_ => console.log('报警音开始播放'))
          .catch(e => {
            // 忽略中断错误
            if (e.name !== 'AbortError') {
              console.error('播放报警音失败:', e);
            }
          });
      }
    },
    stopAlertSound() {
      if (this.alertAudio) {
        this.alertAudio.pause();
        this.alertAudio.currentTime = 0;
        this.alertAudio = null; // 清除引用
      }
    },
    attemptReconnect() {
      if (this.reconnectAttempts < this.maxReconnectAttempts) {
        this.reconnectAttempts++
        const delay = Math.min(5000, 1000 * this.reconnectAttempts) // 指数退避

        console.log(`尝试重新连接 (${this.reconnectAttempts}/${this.maxReconnectAttempts})...`)

        setTimeout(() => {
          if (!this.mqttConnected) {
            this.initMQTT()
          }
        }, delay)
      } else {
        console.error('达到最大重连尝试次数')
      }
    }
  },
  beforeDestroy() {
    // 组件销毁前取消订阅并断开连接
    if (this.mqttClient) {
      this.mqttClient.unsubscribe('$FAMS/OTU/+/alarm')
      this.mqttClient.disconnect()
    }
  }
}
</script>

<style scoped>
#app .theme-picker {
  display: none;
}

.connection-banner {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  background-color: #ff5252;
  color: white;
  padding: 8px;
  text-align: center;
  z-index: 1000;
}
</style>
